package com.cndw.kungfu.model.undercity;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cndw.kungfu.config.Constants;
import com.cndw.kungfu.config.ConstantsDailyItem;
import com.cndw.kungfu.config.ConstantsIntKey;
import com.cndw.kungfu.config.ConstantsLog;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.core.cache.CacheMonster;
import com.cndw.kungfu.domain.Monster;
import com.cndw.kungfu.domain.MonsterAi;
import com.cndw.kungfu.domain.MonsterDeploy;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.domain.Undercity;
import com.cndw.kungfu.ext.LangUtil;
import com.cndw.kungfu.ext.LanguageLib;
import com.cndw.kungfu.ext.LogUtil;
import com.cndw.kungfu.ext.TimeProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.DataSerialize;
import com.cndw.kungfu.model.battle.Team;
import com.cndw.kungfu.model.sys.ChatMain;
import com.cndw.kungfu.model.sys.LogServer;
import com.cndw.kungfu.vo.PassThroughRecordVO;

@Service
public class UndercityServer {

	@Autowired
	private CacheMonster cacheMonster;

	private static final Map<Long, PlayerUndercity> UNDER_MAP = new ConcurrentHashMap<Long, PlayerUndercity>();
	private static Map<Integer, RankingContainer> recordRanking = null;

	private synchronized void addContainer(int undercityId) {
		if (!recordRanking.containsKey(undercityId)) {
			Undercity uc = getUndercity(undercityId);
			if (uc.getType() == Undercity.typePicCheckpoint) {
				recordRanking.put(undercityId, new RankingContainer(ConstantsModel.undercityRankingNum));
			} else if (uc.getType() == Undercity.typeSoldierCheckpoint) {
				recordRanking.put(undercityId, new RankingContainer(ConstantsModel.undercitySCPRankingNum));
			}
		}
	}

	/**
	 * 获取排行榜
	 */
	public RankingContainer getRankings(int undercityId) {
		if (recordRanking == null) {
			init();
		}
		RankingContainer rc = null;
		if (!recordRanking.containsKey(undercityId)) {
			addContainer(undercityId);
		}
		rc = recordRanking.get(undercityId);
		if (rc != null) {
			synchronized (rc) { /* 屏蔽添加排行没有完成时读取了冗余的数据 */
				return rc;
			}
		} else {
			return null;
		}
	}

	public Collection<PassThroughRecordVO> getRankings(int undercityId, int size) {
		Collection<PassThroughRecordVO> records = getRankings(undercityId);
		if (records.size() > size) {
			records = new LinkedList<PassThroughRecordVO>(records).subList(0, size);
		}
		return records;
	}

	private synchronized void init() {
		if (recordRanking == null) {
			recordRanking = DataSerialize.getInstance().getPassThoughRanking();
		}
	}

	public Monster getMonster(int id) {
		return Context.getCacheCenter().getMonsterById(id);
	}

	public MonsterDeploy getDeployById(int monsterDeployId) {
		return Context.getCacheCenter().getMonsterDeployById(monsterDeployId);
	}

	public MonsterAi getMonsterAi(int id) {
		return cacheMonster.getMonsterAi(id);
	}

	public List<MonsterDeploy> getDeploys(int sceneId) {
		return Context.getCacheCenter().getMonsterDeploysBySceneId(sceneId);
	}

	/**
	 * 获取地下城
	 * 
	 * @param undercityId
	 * @return
	 */
	public Undercity getUndercity(int undercityId) {
		return Context.getCacheCenter().getUndercity(undercityId);
	}

	public Collection<Undercity> getuUndercities() {
		return Context.getCacheCenter().getuUndercities();
	}

	/**
	 * 获取一个副本,如果没有就新建立一个.
	 * 
	 * @param playerId
	 * @param undercityId
	 * @return
	 */
	public PlayerUndercity getPlayerUndercity(long playerId) {
		return UNDER_MAP.get(playerId);
	}

	/**
	 * 初始化一个副本
	 * 
	 * @param playerId
	 * @param undercityId
	 */
	public PlayerUndercity initPlayerUnderCity(int undercityId, int enterSceneId, Player player) {
		Undercity undercity = getUndercity(undercityId);
		if (undercity == null) {
			return null;
		}

		PlayerUndercity playerUndercity = new PlayerUndercity(player.getPlayerId(), undercityId);
		playerUndercity.openSecne(enterSceneId);
		Team team = player.getTeam();
		if (team != null) {
			for (long playerId : team.getMemberIds()) {
				UNDER_MAP.put(playerId, playerUndercity);
			}
			playerUndercity.setMemberIds(team.getMemberIds());
		} else {
			UNDER_MAP.put(player.getPlayerId(), playerUndercity);
		}
		return playerUndercity;
	}

	// 退出副本
	public boolean gcUndercity(long playerId) {
		if (UNDER_MAP.containsKey(playerId)) {
			UNDER_MAP.remove(playerId);
			return true;
		} else {
			return false;
		}

	}

	/**
	 * 排行
	 */
	private void rank(long playerId, int undercityId, int spendTime, int sortLevel) {
		Player player = Context.getPlayerServer().getByPlayerId(playerId);
		RankingContainer ranking = getRankings(undercityId);
		if (ranking != null) {
			PassThroughRecordVO ptr = new PassThroughRecordVO();
			ptr.setLevel(player.getLevel());
			ptr.setName(player.getPlayerName());
			ptr.setSpendTime(spendTime);
			ptr.setSortLevel(sortLevel);
			ptr.setPlayerId(playerId);
			ptr.setVocationId(player.getVocationId());
			ptr.setTime(TimeProcesser.getUnixTime());
			if (ranking.add(ptr)) {
				DataSerialize.getInstance().commitSync();
			}
		}
	}

	/**
	 * 副本通关
	 * 
	 * @param playerId
	 * @param undercityId
	 * @param spendTime
	 */
	public void passThroug(long playerId, int sceneId, int undercityId, int enterTime, int endTime) {
		Undercity undercity = getUndercity(undercityId);
		boolean isPicCp = undercity.getType() == Undercity.typePicCheckpoint;
		boolean isSoldierCp = undercity.getType() == Undercity.typeSoldierCheckpoint;
		final Player player = Context.getPlayerServer().getByPlayerId(playerId);
		PlayerUndercity playerUndercity = getPlayerUndercity(playerId);
		if (playerUndercity == null) {
			LogUtil.getMain().error("playerUndercity err " + playerId);
			return;
		}
		// 通天图通关
		int spendTime = endTime - enterTime;
		if (isPicCp) {
			if (undercity.getExitSceneId() == sceneId && spendTime < ConstantsModel.undercityPicCheckPointLimitTime) {
				playerUndercity.setPassThroug(true);
				rank(playerId, undercityId, spendTime, 0);
				int sortLevel = player.getDataInfo().intDataGet(ConstantsIntKey.picCpPass);
				if (sortLevel == undercity.getSortLevel()) {
					player.getDataInfo().intDataSet(ConstantsIntKey.picCpPass, sortLevel + 1);
					player.getDataInfo().commitSync();
					playerUndercity.setRewardId(undercity.getAwardId());
					LogServer.recordLog(player, ConstantsLog.battle, 40009, sortLevel);
				}
			}
		} else if (isSoldierCp) {// 神兵阵通关
			playerUndercity.setPassThroug(true);
			int passLevel = player.getDataInfo().intDataGet(ConstantsIntKey.soldierCpPass);
			if (passLevel >= 2 && passLevel <= ConstantsModel.undercitySoldierMax + 1 && undercity.getSceneIdsArr()[passLevel - 2] == sceneId) {
				rank(playerId, undercityId, spendTime, passLevel - 1);
			} else if (passLevel >= 1 && passLevel <= ConstantsModel.undercitySoldierMax) {
				int level = 1;
				for (int s : undercity.getSceneIdsArr()) {
					if (s == sceneId) {
						break;
					}
					level++;
				}
				if (level >= passLevel) {
					passLevel = level;
					if (passLevel % 10 == 0) {
						// 每通过十层广播
						String msg;
						Monster monster = Context.getCacheCenter().getMonsterById(ConstantsModel.undercityScpBossId[passLevel / 10 - 1]);
						if (passLevel < ConstantsModel.undercitySoldierMax) {
							// msg =
							// LanguageLib.get("undercity.soldier.passthroug",
							// player.getPlayerName(), passLevel,
							// monster.getName(), passLevel);
							msg = LanguageLib.get("undercity.soldier.passthroug", LangUtil.makeNameLink(player), passLevel, monster.getName(), passLevel + 1);
						} else {
							// msg =
							// LanguageLib.get("undercity.soldier.passall",player.getPlayerName(),
							// monster.getName());
							msg = LanguageLib.get("undercity.soldier.passall", LangUtil.makeNameLink(player), monster.getName());
						}
						ChatMain.systemMessageDelay(msg, endTime - TimeProcesser.getUnixTime() + ConstantsModel.undericityScpBcDelayTime);
					}
					rank(playerId, undercityId, spendTime, passLevel);
					undercity.getSceneIdsArr();
					player.getDataInfo().intDataSet(ConstantsIntKey.soldierCpPass, passLevel + 1);
					player.getDataInfo().commitSync();
					Context.getGeneralServer().addTilte(playerId, Constants.titleSCpPass,
							endTime - TimeProcesser.getUnixTime() + ConstantsModel.undericityScpBcDelayTime);

					LogServer.recordLog(player, ConstantsLog.battle, 40010, passLevel);
				}
			}
		} else {
			if (undercity.getExitSceneId() == sceneId) {
				playerUndercity.setPassThroug(true);
				if (undercity.getType() == Undercity.typeSingle) {
					player.getDataInfo().getEveryDay().finishDailyItem(ConstantsDailyItem.singleUndercityItem);
					player.getDataInfo().passUndersAdd(undercityId);// 通关的副本

				} else if (undercity.getType() == Undercity.typeTeam) {
					Team team = player.getTeam();
					if (team != null) {
						Collection<Player> allPlayers = team.getAllPlayers();
						for (Player e : allPlayers) {
							if (e != null) {
								e.getDataInfo().getEveryDay().finishDailyItem(ConstantsDailyItem.teamUndercityItem);
							}
						}
					} else {
						player.getDataInfo().getEveryDay().finishDailyItem(ConstantsDailyItem.teamUndercityItem);
					}
				} else if (undercity.getType() == Undercity.typeDrama) {// 通关剧情副本
					player.getDataInfo().intDataSet(ConstantsIntKey.dreamId, undercity.getId());
					player.getDataInfo().commitSync();
					LogServer.recordLog(player, ConstantsLog.battle, 40014, undercity.getName(), undercity.getId());
				}else if (undercity.getType() == Undercity.typeFamAne) {
					player.getDataInfo().getEveryDay().underCityTimesIncrement(undercityId);
					int anePass = player.getDataInfo().intDataGet(ConstantsIntKey.anePass);
					if (anePass < undercityId) {
						player.getDataInfo().intDataSet(ConstantsIntKey.anePass, undercityId);
					}
					player.getDataInfo().commitSync();
					
				} else if (undercity.getType() == Undercity.typeUnion) {// 通关帮派副本
					Team team = player.getTeam();
					if (team != null) {
						Collection<Player> allPlayers = team.getAllPlayers();
						for (Player e : allPlayers) {
							if (e != null) {
								player.getDataInfo().passUndersAdd(undercityId);// 通关的副本
							}
						}
					} else {
						player.getDataInfo().passUndersAdd(undercityId);// 通关的副本
					}

				}
			}
		}
	}

	/**
	 * 获取undercityId
	 * 
	 * @param sortLevel
	 *            第几关
	 * @param type
	 *            1 通天图 2 神兵阵
	 * @return
	 */
	public Undercity getUndercity(int sortLevel, int type) {
		if (type == 1) {
			sortLevel = sortLevel > ConstantsModel.undercityPicCpIds.length ? ConstantsModel.undercityPicCpIds.length : sortLevel;
			return getUndercity(ConstantsModel.undercityPicCpIds[sortLevel - 1]);
		} else if (type == 2) {
			sortLevel = sortLevel > ConstantsModel.undercitySoldierMax ? ConstantsModel.undercitySoldierMax : sortLevel;
			return getUndercity(ConstantsModel.undercitySoldierCpId);
		}
		return null;
	}

	/**
	 * 获得神兵阵排行榜
	 */
	public Collection<PassThroughRecordVO> getSCPRanking() {
		return getRankings(ConstantsModel.undercitySoldierCpId, ConstantsModel.undercitySCPRankingNum);
	}

	/**
	 * Vip4级玩家增加神兵阵跳关经验
	 * 
	 * @param playerId
	 */
	@Deprecated
	public int addScpExp(long playerId, int level) {
		Player player = Context.getPlayerServer().getByPlayerId(playerId);
		int exp = 0;
		if (level >= 5 && level < ConstantsModel.undercitySoldierMax) {
			exp = ConstantsModel.undercityScpExpAdd[level / 5 - 1];

			player.alterExp(exp);
			player.commitSync();
		}
		return exp;
	}

	/**
	 * 场景内跳关经验
	 * 
	 * @param playerId
	 *            玩家id
	 * @param level
	 *            目标关数
	 * @param levelNow
	 *            当前关数
	 * @return int 获得经验值
	 */
	public int addScpExp(long playerId, int level, int levelNow) {
		Player player = Context.getPlayerServer().getByPlayerId(playerId);
		int exp = 0;

		try {
			if (level >= 5 && level <= ConstantsModel.undercitySoldierMax) {
				if (levelNow != 0) {
					int indexId = level / 5 - 1;
					if (indexId >= 1) {
						exp = ConstantsModel.undercityScpExpAdd[indexId] - ConstantsModel.undercityScpExpAdd[indexId - 1];
					} else {
						exp = ConstantsModel.undercityScpExpAdd[indexId];
					}

					// if (levelNow % 10 == 0) {
					// exp = NumberProcesser.percentOnlyAddValue(exp, 40);
					// }else {
					// exp = NumberProcesser.percentOnlyAddValue(exp, 60);
					// }
				} else {
					// 进入神兵阵
					exp = ConstantsModel.undercityScpExpAdd[level / 5 - 1];
				}

				player.alterExp(exp);
				player.commitSync();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return exp;
	}

	public int getBuyCost(int times) {
		return 10 + times * 2;
	}

	public int getBuyRateCost(int enterTimes) {
		if (enterTimes <= 5) {
			return 20;
		} else if (enterTimes <= 10) {
			return 25;
		} else {
			return enterTimes * 3;
		}
	}

}